package com.ruoyi.yipaiju.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.XcxUser;
import com.ruoyi.common.enums.DueDiligenceReportEnums;
import com.ruoyi.common.enums.JsonHierarchyEnums;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.bean.Builder;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.http.HttpRequest;
import com.ruoyi.common.utils.http.HttpRespons;
import com.ruoyi.common.utils.http.RestTemplateUtil;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.yipaiju.domain.DiligenceReportOrder;
import com.ruoyi.yipaiju.domain.ForeclosedHouse;
import com.ruoyi.yipaiju.domain.StorageRelationship;
import com.ruoyi.yipaiju.domain.vo.CommonEntityVO;
import com.ruoyi.yipaiju.domain.vo.ReportResultVO;
import com.ruoyi.yipaiju.mapper.DiligenceReportOrderMapper;
import com.ruoyi.yipaiju.service.*;
import com.ruoyi.yipaiju.utils.DueDiligenceReportGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 尽调报告订单Service业务层处理
 * 
 * @author liuwp
 * @date 2025-08-06
 */
@Service
public class DiligenceReportOrderServiceImpl implements IDiligenceReportOrderService 
{

    private static final Logger log = LoggerFactory.getLogger(DiligenceReportOrderServiceImpl.class);

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private IWechatService wechatService;

    @Autowired
    private IXcxUserService xcxUserService;

    @Autowired
    private DiligenceReportOrderMapper diligenceReportOrderMapper;

    @Autowired
    private IStorageRelationshipService storageRelationshipService;
    @Autowired
    private IForeclosedHouseService foreclosedHouseService;

    /**
     * 查询尽调报告订单
     * 
     * @param id 尽调报告订单主键
     * @return 尽调报告订单
     */
    @Override
    public DiligenceReportOrder selectDiligenceReportOrderById(Long id)
    {
        return diligenceReportOrderMapper.selectDiligenceReportOrderById(id);
    }

    /**
     * 查询尽调报告订单列表
     * 
     * @param diligenceReportOrder 尽调报告订单
     * @return 尽调报告订单
     */
    @Override
    public List<DiligenceReportOrder> selectDiligenceReportOrderList(DiligenceReportOrder diligenceReportOrder)
    {
        return diligenceReportOrderMapper.selectDiligenceReportOrderList(diligenceReportOrder);
    }

    /**
     * 根据业务主键查询一条记录：尽调报告订单
     *
     * @param diligenceReportOrder 尽调报告订单
     * @return 尽调报告订单
     */
    @Override
    public DiligenceReportOrder selectOneDiligenceReportOrder(DiligenceReportOrder diligenceReportOrder)
    {
        return diligenceReportOrderMapper.selectOneDiligenceReportOrder(diligenceReportOrder);
    }

    /**
     * 新增尽调报告订单
     * 
     * @param diligenceReportOrder 尽调报告订单
     * @return 结果
     */
    @Override
    public int insertDiligenceReportOrder(DiligenceReportOrder diligenceReportOrder)
    {
        return diligenceReportOrderMapper.insertDiligenceReportOrder(diligenceReportOrder);
    }

    /**
     * 修改尽调报告订单
     * 
     * @param diligenceReportOrder 尽调报告订单
     * @return 结果
     */
    @Override
    public int updateDiligenceReportOrder(DiligenceReportOrder diligenceReportOrder)
    {
        return diligenceReportOrderMapper.updateDiligenceReportOrder(diligenceReportOrder);
    }

    @Override
    public int updateDiligenceReportOrderCondition(DiligenceReportOrder diligenceReportOrder, DiligenceReportOrder diligenceReportOrderCondition)
    {
        return diligenceReportOrderMapper.updateDiligenceReportOrderCondition(diligenceReportOrder, diligenceReportOrderCondition);
    }

    /**
     * 批量删除尽调报告订单
     * 
     * @param ids 需要删除的尽调报告订单主键
     * @return 结果
     */
    @Override
    public int deleteDiligenceReportOrderByIds(Long[] ids)
    {
        return diligenceReportOrderMapper.deleteDiligenceReportOrderByIds(ids);
    }

    /**
     * 删除尽调报告订单信息
     * 
     * @param id 尽调报告订单主键
     * @return 结果
     */
    @Override
    public int deleteDiligenceReportOrderById(Long id)
    {
        return diligenceReportOrderMapper.deleteDiligenceReportOrderById(id);
    }

    /**
     * 条件删除尽调报告订单
     *
     * @param diligenceReportOrder 尽调报告订单
     * @return 结果
     */
    @Override
    public int deleteDiligenceReportOrderByCondition(DiligenceReportOrder diligenceReportOrder)
    {
        return diligenceReportOrderMapper.deleteDiligenceReportOrderByCondition(diligenceReportOrder);
    }

    @Override
    public boolean createPdf(DiligenceReportOrder diligenceReportOrder) {
        int i = 0;
        while (i < 3){
            try {
                // TODO 如果是ai报告需要发送pdf报告
                if (diligenceReportOrder.getProductId() == 2){
                    long foreclosedId = diligenceReportOrder.getForeclosedId();//房源id
                    // TODO 调用接口获取报告数据 生成pdf
                    Map<String, Object> map = queryReportResultVO(foreclosedId);
                    String filePath = RuoYiConfig.getUploadPath() + "/ai_report/" + DateUtils.datePath();
                    String fileName = "AI_" + diligenceReportOrder.getOutTradeNo() + "_"+System.currentTimeMillis()+".pdf";
                    File absoluteFile = FileUploadUtils.getAbsoluteFile(filePath, fileName);
                    DueDiligenceReportGenerator.createPdf(absoluteFile.getPath() , map);
                    diligenceReportOrder.setReport2Path(filePath.replace(RuoYiConfig.getProfile(), Constants.RESOURCE_PREFIX) + File.separator +fileName);
                    log.info("订单号：{}，生成pdf成功：{}", diligenceReportOrder.getOutTradeNo(), absoluteFile.getPath());
                    return true;
                }
            }catch (Exception e) {
                e.printStackTrace();
                log.info("订单号：{}，生成pdf异常：{}", diligenceReportOrder.getOutTradeNo(), e.getMessage());
            }
            i++;
        }
        return false;
    }

    @Override
    public boolean sendTeplateMessage(DiligenceReportOrder diligenceReportOrder, String tip) {
        try {
            // TODO 等页面确认在开发
            String appid = configService.selectConfigByKey("biz.wechat.xcx.appid");
            String secret = configService.selectConfigByKey("biz.wechat.xcx.secret");
            String access_token = wechatService.getAccessToken(appid, secret);

            XcxUser xcxUser = xcxUserService.selectXcxUserById(diligenceReportOrder.getXcxUserId());
            if (xcxUser != null) {
                String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token="+access_token;
                String data = "{\n" +
                        "  \"touser\": \""+xcxUser.getOpenid()+"\",\n" +
                        "  \"template_id\": \"np3lVHUFfQYAxvXSqom9T3hgDTTXfwVIE8nLZe0xw8c\",\n" +
                        "  \"page\": \"/subpackages/pages/order-list/order-list?orderId="+diligenceReportOrder.getId()+"\",\n" +   // TODO 订单列表的页面  需要和雨竹确定
                        "  \"data\": {\n" +
                        "      \"character_string1\": {\n" +
                        "          \"value\": \""+ diligenceReportOrder.getOutTradeNo() + "\"\n" +
                        "      },\n" +
                        "      \"amount4\": {\n" +
                        "          \"value\": \""+ diligenceReportOrder.getTotalFee().divide(new BigDecimal(100)).setScale(2, RoundingMode.HALF_UP) +"\"\n" +
                        "      },\n" +
                        "      \"thing6\": {\n" +
                        "          \"value\": \""+diligenceReportOrder.getPayBody()+"\"\n" +
                        "      } ,\n" +
                        "      \"thing5\": {\n" +
                        "          \"value\": \""+tip+"\"\n" +
                        "      } ,\n" +
                        "      \"time7\": {\n" +
                        "          \"value\": \""+DateUtils.getTime()+"\"\n" +
                        "      }\n" +
                        "  }\n" +
                        "}";

                HttpRequest httpRequest = new HttpRequest();
                HttpRespons httpRespons = httpRequest.sendPost(url, data);
                log.info("订单号：{}，发送模板消息结果：{}", diligenceReportOrder.getOutTradeNo(), httpRespons.getContent());
                return true;
            }
        }catch (Exception e) {
            e.printStackTrace();
            log.info("订单号：{}，发送模板消息异常：{}", diligenceReportOrder.getOutTradeNo(), e.getMessage());
        }
        return false;
    }


    public Map<String, Object> queryReportResultVO(Long foreclosedId){
        Map<String, Object> map = new HashMap<>();
        // 发送pdf报告
        String url = RuoYiConfig.getReportUrl();
        String data = "{\n" +
                "    \"houses_id\": \""+foreclosedId+"\"\n" +
                "}";
        try {
            String result = RestTemplateUtil.sendPost(url, data);
            log.info("请求成功，响应结果: " + result);
            JSONObject jsonObject = JSON.parseObject(result);
            // 获取 data 数组
            JSONArray dataArray = jsonObject.getJSONArray("data");
            JSONObject resultData = null;
            // 遍历数组，找到 type="data" 的对象
            for (int i = 0; i < dataArray.size(); i++) {
                JSONObject obj = dataArray.getJSONObject(i);
                if ("data".equals(obj.getString("type"))) {
                    // 获取红框中的 data 数据
                    JSONObject dataResult = obj.getJSONObject("data");
                    if(dataResult.getJSONObject(DueDiligenceReportEnums.ANSWER.getCode()) != null){
                        resultData = dataResult.getJSONObject(DueDiligenceReportEnums.ANSWER.getCode());
                    }else {
                        resultData = dataResult;
                    }
                    break;
                }
            }
            map = queryMap(resultData, foreclosedId);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("请求失败: " + e.getMessage());
        }
        return map;
    }

    /**
     * 组装map
     * @param resultData
     * @return
     */
    public Map<String, Object> queryMap(JSONObject resultData, Long foreclosedId){
        Map<String, Object> map = new HashMap<>();
        try{
            if(resultData != null){
                //前沿
                ReportResultVO frontier = queryReportResult(resultData.getJSONObject(DueDiligenceReportEnums.FRONTIER.getCode()), DueDiligenceReportEnums.FRONTIER.getCode(), JsonHierarchyEnums.ONE.getCode());
                map.put("frontier",frontier);
                //基本信息
                ReportResultVO basicInfo = queryReportResult(resultData.getJSONObject(DueDiligenceReportEnums.BASICINFO.getCode()), DueDiligenceReportEnums.BASICINFO.getCode(), JsonHierarchyEnums.TWO.getCode());
                map.put("basicInfo",basicInfo);
                //拍卖信息
                ReportResultVO auctionInfo = queryReportResult(resultData.getJSONObject(DueDiligenceReportEnums.AUCTIONINFO.getCode()), DueDiligenceReportEnums.AUCTIONINFO.getCode(), JsonHierarchyEnums.TWO.getCode());
                map.put("auctionInfo",auctionInfo);
                //图像信息
                ReportResultVO imageInfo = queryReportResult(resultData.getJSONObject(DueDiligenceReportEnums.IMAGEINFO.getCode()), DueDiligenceReportEnums.IMAGEINFO.getCode(), JsonHierarchyEnums.TWO.getCode());
                map.put("imageInfo",imageInfo);
                // 图片从表里拿
                ForeclosedHouse foreclosedHouse = foreclosedHouseService.selectForeclosedHouseById(foreclosedId);
                if(foreclosedHouse != null){
                    List<StorageRelationship> storageRelationships = storageRelationshipService.selectStorageRelationshipList(Builder.of(StorageRelationship::new).with(StorageRelationship::setRelatedObjectId, foreclosedHouse.getNameMd5()).build());
                    if (storageRelationships.size() > 0){
                        // 获取所有id的集合
                        List<String> imageInfos = storageRelationships.stream().map(StorageRelationship::getFilename).collect(Collectors.toList());
                        map.put("imageInfos",imageInfos);
                    }
                }
                //价值研究
                ReportResultVO valueResearch = queryReportResult(resultData.getJSONObject(DueDiligenceReportEnums.VALUERESEARCH.getCode()), DueDiligenceReportEnums.VALUERESEARCH.getCode(), JsonHierarchyEnums.TWO.getCode());
                map.put("valueResearch",valueResearch);
                //所有权信息
                ReportResultVO ownershipInfo = queryReportResult(resultData.getJSONObject(DueDiligenceReportEnums.OWNERSHIPINFO.getCode()), DueDiligenceReportEnums.OWNERSHIPINFO.getCode(), JsonHierarchyEnums.THR.getCode());
                map.put("ownershipInfo",ownershipInfo);
                //成本信息
                ReportResultVO costInfo = queryReportResult(resultData.getJSONObject(DueDiligenceReportEnums.COSTINFO.getCode()), DueDiligenceReportEnums.COSTINFO.getCode(), JsonHierarchyEnums.TWO.getCode());
                map.put("costInfo",costInfo);
                //风险信息
                ReportResultVO riskInfo = queryReportResult(resultData.getJSONObject(DueDiligenceReportEnums.RISKINFO.getCode()), DueDiligenceReportEnums.RISKINFO.getCode(), JsonHierarchyEnums.THR.getCode());
                map.put("riskInfo",riskInfo);
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.error("请求失败: " + e.getMessage());
        }
        return map;

    }
    /**
     * 获取结果
     * @param resultData
     * @return
     */
    public ReportResultVO queryReportResult(JSONObject resultData, String code, int type){
        if(resultData == null || resultData.isEmpty()){
            return null;
        }
        // 创建 ReportResultVO 对象
        ReportResultVO reportResultVO = new ReportResultVO();
        reportResultVO.setComment(resultData.getString("comment"));
        reportResultVO.setCode(code);
        String value = resultData.getString("value");
        if(type == 1){
            reportResultVO.setValue(value);
        }
        if(!"".equals(value) && isJsonArray(value) && type == 2){
            List<CommonEntityVO> entityVOS = queryTwoEntityVO(value);
            reportResultVO.setValues(entityVOS);
        }

        if(!"".equals(value) && isJsonArray(value) && type == 3){
            List<CommonEntityVO> entityVOList = new ArrayList<>();
            JSONObject originalObj = JSON.parseObject(value);
            Set<String> keys = originalObj.keySet();
            for (String key : keys) {
                JSONObject obj = originalObj.getJSONObject(key);
                CommonEntityVO entityVO = new CommonEntityVO();
                entityVO.setCode(key);
                entityVO.setComment(obj.getString("comment"));
                List<CommonEntityVO> entityVOS = queryTwoEntityVO(obj.getString("value"));
                entityVO.setValues(entityVOS);
                entityVOList.add(entityVO);
            }
            reportResultVO.setValues(entityVOList);
        }
        return reportResultVO;
    }

    public List<CommonEntityVO> queryTwoEntityVO(String value){
        List<CommonEntityVO> entityVOS = new ArrayList<>();
        JSONObject originalObj = JSON.parseObject(value);
        Set<String> keys = originalObj.keySet();
        for (String key : keys) {
            JSONObject obj = originalObj.getJSONObject(key);
            CommonEntityVO entityVO = new CommonEntityVO();
            entityVO.setCode(key);
            entityVO.setComment(obj.getString("comment"));
            entityVO.setValue(obj.getString("value"));
            entityVOS.add(entityVO);
        }
        return entityVOS;
    }

    /**
     * 判断字符串是否为 JSONArray 格式
     * @param jsonStr
     * @return
     */
    public boolean isJsonArray(String jsonStr) {
        try {
            // 解析为JSONObject
            JSONObject originalObj = JSON.parseObject(jsonStr);
            // 创建目标JSONArray
            JSONArray resultArray = new JSONArray();
            // 获取所有键并遍历
            Set<String> keys = originalObj.keySet();
            for (String key : keys) {
                // 为每个键值对创建一个新的JSONObject
                JSONObject keyValueObj = new JSONObject();
                keyValueObj.put(key, originalObj.getJSONObject(key));
                // 添加到数组
                resultArray.add(keyValueObj);
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }

}
